/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup TeeTrusted
 * @{
 *
 * @brief TEE（Trusted Excution Environment）可信执行环境API。
 *
 * 提供安全能力API，例如可信存储、加解密及可信时间等，用于可信应用程序开发。
 *
 * @since 20
 */

/**
 * @file tee_client_api.h
 *
 * @brief 定义了供可信应用（TA）访问的客户端应用（CA）API。
 *
 * 示例：
 * 1. 初始化TEE：调用TEEC_InitializeContext来初始化TEE。
 * 2. 打开会话：调用TEEC_OpenSession并传入可信应用 (TA) 的通用唯一标识符 (UUID)。
 * 3. 发送命令：调用TEEC_InvokeCommand向TA发送命令。
 * 4. 关闭会话：调用TEEC_CloseSession关闭会话。
 * 5. 关闭 TEE：调用TEEC_FinalizeContext关闭TEE。
 *
 * @library libteec.so
 * @kit TEEKit
 * @include <TEEKit/tee_client_api.h>
 * @syscap SystemCapability.Tee.TeeClient
 * @since 20
 */

#ifndef TEE_CLIENT_API_H
#define TEE_CLIENT_API_H

#include <string.h>
#include "tee_client_type.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 定义了在REE（普通执行环境）与TEE（可信执行环境）之间传输的参数值。
 *
 * @since 20
 */
#define TEEC_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \
    ((param3Type) << 12 | (param2Type) << 8 | (param1Type) << 4 | (param0Type))

/**
 * @brief 定义由paramTypes和index指定的参数值。
 *
 * @since 20
 */
#define TEEC_PARAM_TYPE_GET(paramTypes, index) \
    (((paramTypes) >> (4*(index))) & 0x0F)

/**
 * @brief 初始化TEE（可信执行环境）。
 *
 * 必须在打开会话或发送命令之前初始化TEE。
 * 初始化完成后，客户端应用（CA）与TEE之间将建立连接。
 *
 * @param name [IN]指向TEE路径的指针。
 * @param context [IN/OUT]指向上下文的指针，该指针是TEE的句柄。
 *
 * @return TEEC_SUCCESS：TEE成功初始化。\n
 *         TEEC_ERROR_BAD_PARAMETERS：name不正确或context为null。\n
 *         TEEC_ERROR_GENERIC：系统资源不足。
 * @since 20
 */
TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context);

/**
 * @brief 关闭TEE。
 *
 * TEE关闭后，客户端应用（CA）将与TEE断开连接。
 *
 * @param context [IN/OUT]指向已成功初始化的TEE的指针。
 *
 * @since 20
 */
void TEEC_FinalizeContext(TEEC_Context *context);

/**
 * @brief 打开一个会话。
 *
 * 此函数用于在指定TEE上下文中，为客户端应用（CA）与指定UUID的可信应用（TA）建立连接。\n
 * 传输的数据包含在operation中。\n
 * 如果会话成功打开，则返回的session提供连接的描述。\n
 * 如果会话打开失败，则返回returnOrigin表示失败的原因。
 *
 * @param context [IN/OUT]指向已成功初始化的TEE的指针。
 * @param session [OUT]指向会话的指针。该值不能为空。
 * @param destination [IN]指向目标TA的UUID的指针。每个TA都有唯一的UUID。
 * @param connectionMethod [IN]指示连接方法。详情请参见TEEC_LoginMethod。
 * @param connectionData [IN]指向连接数据的指针，该值根据连接模式而变化。
 * 如果连接模式为TEEC_LOGIN_PUBLIC、TEEC_LOGIN_USER、
 * TEEC_LOGIN_USER_APPLICATION或TEEC_LOGIN_GROUP_APPLICATION，则连接数据必须为null。
 * 如果连接模式为TEEC_LOGIN_GROUP或TEEC_LOGIN_GROUP_APPLICATION，
 * 则连接数据必须指向一个uint32_t类型的数据，表示CA需连接的目标用户组。
 * @param operation [IN/OUT]指向CA与TA之间传输数据的指针。
 * @param returnOrigin [IN/OUT]指向错误来源的指针。
 *
 * @return TEEC_SUCCESS：会话成功打开。\n
 *         TEEC_ERROR_BAD_PARAMETERS：context、session或destination为空。\n
 *         TEEC_ERROR_ACCESS_DENIED：访问请求被拒绝。\n
 *         TEEC_ERROR_OUT_OF_MEMORY：系统资源不足。\n
 *         TEEC_ERROR_TRUSTED_APP_LOAD_ERROR：TA加载失败。\n
 * @since 20
 */
TEEC_Result TEEC_OpenSession(TEEC_Context *context, TEEC_Session *session, const TEEC_UUID *destination,
    uint32_t connectionMethod, const void *connectionData, TEEC_Operation *operation, uint32_t *returnOrigin);

/**
 * @brief 关闭会话。
 *
 * 会话关闭后，客户端应用（CA）将与可信应用（TA）断开连接。
 *
 * @param session [IN/OUT]指向要关闭的会话的指针。
 *
 * @since 20
 */
void TEEC_CloseSession(TEEC_Session *session);

/**
 * @brief 向TA发送命令。
 *
 * 客户端应用（CA）通过指定的会话向TA发送命令ID。
 *
 * @param session [IN/OUT]指向已打开的会话的指针。
 * @param commandID [IN]指定TA支持的命令ID，由TA定义。
 * @param operation [IN/OUT]指向从CA向TA发送的数据的指针。
 * @param returnOrigin [IN/OUT]指向错误来源的指针。
 *
 * @return TEEC_SUCCESS：命令发送成功。\n
 *         TEEC_ERROR_BAD_PARAMETERS：session为空或operation格式错误。\n
 *         TEEC_ERROR_ACCESS_DENIED：访问请求被拒绝。\n
 *         TEEC_ERROR_OUT_OF_MEMORY：系统资源不足。\n
 * @since 20
 */
TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, uint32_t commandID,
    TEEC_Operation *operation, uint32_t *returnOrigin);

/**
 * @brief 在指定TEE上下文中注册共享内存。
 *
 * 注册的共享内存可以实现零拷贝。\n
 * 零拷贝功能还需要操作系统的支持。\n
 * 目前无法以此方式实现零拷贝。
 *
 * @param context [IN/OUT]指向已成功初始化的TEE的指针。
 * @param sharedMem [IN/OUT]指向共享内存的指针。
 * 该指针指向的共享内存不能为空，且其大小不能为 0。
 *
 * @return TEEC_SUCCESS：操作成功。\n
 *         TEEC_ERROR_BAD_PARAMETERS：<b>context</b>、<b>sharedMem</b> 为空或指向的内存为空。
 * @since 20
 */
TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem);

/**
 * @brief 在指定的TEE上下文中请求共享内存。
 *
 * 共享内存可用于在普通执行环境（REE）与可信执行环境（TEE）之间的数据传输中实现零拷贝。\n
 * 零拷贝功能还需要操作系统的支持。\n
 * 无法以此方式实现零拷贝。
 *
 * @attention 如果输入参数sharedMem的size字段设置为0，虽然函数会返回TEEC_SUCCESS，
 * 但该共享内存将无法使用，因为该内存既没有地址也没有大小。
 *
 * @param context [IN/OUT]指向已成功初始化的TEE的指针。
 * @param sharedMem [IN/OUT]指向共享内存的指针。共享内存的大小不能为 0。
 *
 * @return TEEC_SUCCESS：操作成功。\n
 *         TEEC_ERROR_BAD_PARAMETERS：context或sharedMem为空。\n
 *         TEEC_ERROR_OUT_OF_MEMORY：系统资源不足。
 * @since 20
 */
TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, TEEC_SharedMemory *sharedMem);

/**
 * @brief 释放已注册或已获取的共享内存。
 *
 * @attention 如果共享内存是通过TEEC_AllocateSharedMemory获取的，
 * 则释放后该内存会被系统回收；如果共享内存是通过TEEC_RegisterSharedMemory获取的，
 * 则释放后本地内存不会被回收。
 *
 * @param sharedMem [IN/OUT]指向要释放的共享内存的指针。
 *
 * @since 20
 */
void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMem);

/**
 * @brief 取消一个操作。
 *
 * @attention 此操作仅用于发送取消消息。是否执行取消操作由TEE或TA决定。
 * 当前，取消操作不生效。
 *
 * @param operation [IN/OUT]指向从CA到TA发送数据的指针。
 *
 * @since 20
 */
void TEEC_RequestCancellation(TEEC_Operation *operation);

#ifdef __cplusplus
}
#endif

#endif
/** @} */